package br.pucrs.lognplay.repository;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import br.pucrs.lognplay.repository.mapper.jpa.ClientMapper;
import br.pucrs.lognplay.repository.mapper.jpa.DynamicViewMapper;
import br.pucrs.lognplay.repository.mapper.jpa.LogSourceMapper;
import br.pucrs.lognplay.repository.mapper.jpa.StaticViewMapper;
import br.pucrs.lognplay.repository.mapper.jpa.TagMapper;
import br.pucrs.lognplay.repository.mapper.jpa.UserMapper;

public final class RepositoryManager {

	private static final String PERSISTENCE_UNIT_NAME = "lognplay";

	private static final EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);

	private static final ThreadLocal<EntityManager> entityManager = new ThreadLocal<>();

	public static void beginTransaction() {
		assertEntityManagerNull();
		entityManager.set(entityManagerFactory.createEntityManager());
		entityManager.get().getTransaction().begin();
	}

	public static void commitTransaction() {
		assertEntityManagerNotNull();
		entityManager.get().getTransaction().commit();
		entityManager.get().close();
		entityManager.remove();
	}

	public static void rollbackTransaction() {
		assertEntityManagerNotNull();
		entityManager.get().getTransaction().rollback();
		entityManager.get().close();
		entityManager.remove();
	}

	public static ClientRepository getClientRepository() {
		assertEntityManagerNotNull();
		return new ClientMapper(entityManager.get());
	}

	public static DynamicViewRepository getDynamicViewRepository() {
		assertEntityManagerNotNull();
		return new DynamicViewMapper(entityManager.get());
	}

	public static LogSourceRepository getLogSourceRepository() {
		assertEntityManagerNotNull();
		return new LogSourceMapper(entityManager.get());
	}

	public static StaticViewRepository getStaticViewRepository() {
		assertEntityManagerNotNull();
		return new StaticViewMapper(entityManager.get());
	}

	public static TagRepository getTagRepository() {
		assertEntityManagerNotNull();
		return new TagMapper(entityManager.get());
	}

	public static UserRepository getUserRepository() {
		assertEntityManagerNotNull();
		return new UserMapper(entityManager.get());
	}

	private static void assertEntityManagerNull() {
		if (!(entityManager.get() == null)) {
			throw new IllegalStateException("Active transaction found");
		}
	}

	private static void assertEntityManagerNotNull() {
		if (!(entityManager.get() != null)) {
			throw new IllegalStateException("No active transaction found");
		}
	}
}
